//------------------------------------------------------------------------------------------------------
//   _____     _______ ____  _     ___  ____  ____    _____ _   _  ____ ___ _   _ _____   ______  ___ _ 
//  / _ \ \   / / ____|  _ \| |   / _ \|  _ \|  _ \  | ____| \ | |/ ___|_ _| \ | | ____| |  _ \ \/ / / |
// | | | \ \ / /|  _| | |_) | |  | | | | |_) | | | | |  _| |  \| | |  _ | ||  \| |  _|   | | | \  /| | |
// | |_| |\ V / | |___|  _ <| |__| |_| |  _ <| |_| | | |___| |\  | |_| || || |\  | |___  | |_| /  \| | |
//  \___/  \_/  |_____|_| \_\_____\___/|_| \_\____/  |_____|_| \_|\____|___|_| \_|_____| |____/_/\_\_|_|
//
// Overlord Engine v1.82
// Copyright Overlord Thomas Goussaert & Overlord Brecht Kets
// http://www.digitalartsandentertainment.com/
//------------------------------------------------------------------------------------------------------
#pragma once
#include "Graphics\Material.h"

class TextureData;

class UberMaterial : public Material
{
public:
	UberMaterial();
	~UberMaterial();

	void SetDiffuseTexture(const wstring& assetFile);
	void SetSpecularTexture(const wstring& assetFile);
	void SetNormalMapTexture(const wstring& assetFile);
	void SetEnvironmentMapTexture(const wstring& assetFile);
	void SetReflectionStrength(float amount);
	void SetOpacityMap(const wstring& assetFile);

	void SetRefractionStrength(float amount);
	void SetRefractionIndex(float amount);
	void SetOpacity(float amount);
	void SetAmbientIntensity(float amount);
	void SetFresnelPower(float amount);
	void SetFresnelMultiplier(float amount);
	void SetShininess(int amount);

	void SetFresnelFallOff(bool b = true);
	void FlipGreenChannel(bool flip = true);
	void SetSpecularBlinn(bool b = true);
	void SetSpecularPhong(bool b = true);

protected:
	virtual void LoadEffectVariables();
	virtual void UpdateEffectVariables(const GameContext& gameContext, ModelComponent* pModelComponent);

	TextureData* m_pDiffuseTexture;
	TextureData* m_pSpecularTexture;
	TextureData* m_pNormalMapTexture;
	TextureData* m_pEnvironmentMapTexture;
	TextureData* m_TextureOpacity;

	bool m_bDiffuseTexture;
	bool m_bSpecularTexture;
	bool m_bNormalMapTexture;
	bool m_bEnvironmentMapTexture;
	bool m_bOpacityMap;

	bool m_bFresnelFallOff;
	bool m_FlipGreenChannel;
	bool m_SpecularBlinn;
	bool m_SpecularPhong;

	float m_ReflectionStrength;

	float m_RefractionStrength;
	float m_RefractionIndex;
	float m_Opacity;
	float m_AmbientIntensity;
	float m_FresnelPower;
	float m_FresnelMultiplier;
	int m_Shininess;

	static ID3DX11EffectShaderResourceVariable* m_pDiffuseSRVvariable;
	static ID3DX11EffectScalarVariable* m_pDiffuseSBoolvariable;
	static ID3DX11EffectShaderResourceVariable* m_pSpecularSRVvariable;
	static ID3DX11EffectScalarVariable* m_pSpecularSBoolvariable;
	static ID3DX11EffectShaderResourceVariable* m_pNormalMapSRVvariable;
	static ID3DX11EffectScalarVariable* m_pNormalMapSBoolvariable;
	static ID3DX11EffectShaderResourceVariable* m_pEnvironmentSRVvariable;
	static ID3DX11EffectScalarVariable* m_pEnvironmentSBoolvariable;
	static ID3DX11EffectShaderResourceVariable* m_pOpacitySRVvariable;
	static ID3DX11EffectScalarVariable* m_pOpacitySBoolvariable;
	static ID3DX11EffectScalarVariable* m_pReflectionStrengthSFloatvariable;

	static ID3DX11EffectScalarVariable* m_pShininessSFloatvariable;
	static ID3DX11EffectScalarVariable* m_pRefractionStrengthSFloatvariable;
	static ID3DX11EffectScalarVariable* m_pOpacitySFloatvariable;
	static ID3DX11EffectScalarVariable* m_pRefractionIndexSFloatvariable;
	static ID3DX11EffectScalarVariable* m_pAmbientIntensitySFloatvariable;
	static ID3DX11EffectScalarVariable* m_pFresnelPowerSFloatvariable;
	static ID3DX11EffectScalarVariable* m_pFresnelMultiplierSFloatvariable;

	static ID3DX11EffectScalarVariable* m_pFresnelFallOffSBoolvariable;
	static ID3DX11EffectScalarVariable* m_pFlipGreenChannelSBoolvariable;
	static ID3DX11EffectScalarVariable* m_pSpecularBlinnSBoolvariable;
	static ID3DX11EffectScalarVariable* m_pSpecularPhongSBoolvariable;

private:
	// -------------------------
	// Disabling default copy constructor and default 
	// assignment operator.
	// -------------------------
	UberMaterial(const UberMaterial &obj);
	UberMaterial& operator=(const UberMaterial& obj);
};

